#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <thread>
#include<sys/types.h>
#include<sys/stat.h>

#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>

#include <gui/BufferQueue.h>
#include <gui/BufferQueueDefs.h>
#include <gui/ConsumerBase.h>
#include <ui/FenceTime.h>
#include <ui/GraphicBuffer.h>

#include "platform_gralloc4.h" //librga

#include "FakeCameraConsumer.h"
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <fcntl.h>

using namespace android;

#include "common.h"
 
#if 0
int main(int argc, char *argv[])
{
	int clifd, listenfd;
	struct sockaddr_un servaddr, cliaddr;
	int ret;
	socklen_t clilen;
	struct msghdr msg;
	struct iovec iov[1];
	char buf [100];
	char  *testmsg = "test msg.\n";
 
	union {  //对齐
		struct cmsghdr cm;
		char control[CMSG_SPACE(sizeof(int))];
	}  control_un;
	struct cmsghdr  * pcmsg;
	int  recvfd;
 
	listenfd  =  socket ( AF_UNIX ,  SOCK_STREAM ,  0 ) ;
	if(listenfd < 0) {
		printf ( "socket failed.\n" ) ;
		return  -1;
	}
 
	unlink(UNIXSTR_PATH) ;
 
	bzero (&servaddr, sizeof(servaddr));
	servaddr.sun_family = AF_UNIX;
	strcpy ( servaddr.sun_path ,  UNIXSTR_PATH ) ;
 
	ret  =  bind ( listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
	if(ret < 0) {
		printf ( "bind failed. errno = %d.\n" ,  errno ) ;
		close(listenfd);
		return  - 1 ;
	}
 
	listen(listenfd, 5);

    char data_ptr[32];
    int data_len = sizeof(data_ptr);

	while(1) {
		clilen = sizeof( cliaddr );
		clifd = accept( listenfd, (struct sockaddr*)&cliaddr , &clilen);
		if ( clifd < 0 ) {
			printf ( "accept failed.\n" ) ;
			continue ;
		}
 
 RECV_DATA:
        recvfd = -1;
        ret = ipc_fd_socket_recv(clifd, &recvfd, data_ptr, data_len);
        goto RECV_DATA;//test????

		msg.msg_name  = NULL;
		msg.msg_namelen  = 0;
		//设置数据缓冲区
		iov[0].iov_base = buf;
		iov[0].iov_len = 100;
		msg.msg_iov = iov;
		msg.msg_iovlen = 1;
		//设置辅助数据缓冲区和长度
		msg.msg_control = control_un.control;
		msg.msg_controllen  =  sizeof(control_un.control) ;
		//接收
		ret = recvmsg(clifd , &msg, 0);
		if( ret <= 0 ) {
			return ret;
		}
		//检查是否收到了辅助数据，以及长度
		if((pcmsg = CMSG_FIRSTHDR(&msg) ) != NULL && ( pcmsg->cmsg_len == CMSG_LEN(sizeof(int)))) {
			if ( pcmsg->cmsg_level  !=  SOL_SOCKET ) {
				printf("cmsg_leval is not SOL_SOCKET\n");
				continue;
			}
 
			if ( pcmsg->cmsg_type != SCM_RIGHTS ) {
				printf ( "cmsg_type is not SCM_RIGHTS" );
				continue;
			}
			//这就是我们接收的描述符
			recvfd = *((int*)CMSG_DATA(pcmsg));
			printf ( "0000 recv fd = %d\n", recvfd );
 
			//write ( recvfd, testmsg, strlen(testmsg) + 1);

        
            int gb_shared_fd = recvfd;

            if (gb_shared_fd > 0)
            {
                int new_gb_shared_fd = fcntl(gb_shared_fd, F_DUPFD_CLOEXEC, 0);

                printf("gb_shared_fd=%d, new_gb_shared_fd=%d.\n", gb_shared_fd, new_gb_shared_fd);
                

                                   //test fd rga
                    #if 1
                        int src_width = 1920;
                        int src_height = 1080;
                        static unsigned long src_fd = 0;
                        static unsigned long dst_fd = 0;
                        int dst_width = 1920;
                        int dst_height = 1080;
                        int zoom_val = 100;
                        bool mirror = false;
                        bool isNeedCrop = true;
                        bool isDstNV21 = false;
                        bool is16Align = true;
                        bool isYuyvFormat = false;

                        if (src_fd == 0) src_fd = new_gb_shared_fd;

                            //                         camera2::RgaCropScale::rga_nv12_scale_crop(
                            // tempFrameWidth, tempFrameHeight, gb_shared_fd, handle_fd,
                            // halBuf.width, halBuf.height, 100, false, true,
                            // (halBuf.format == PixelFormat::YCRCB_420_SP), is16Align,
                            // false);

                        if (src_fd > 0 && dst_fd > 0)
                        {
                            int ret44 = rga_nv12_scale_crop(
                                src_width, src_height,
                                src_fd, dst_fd,
                                dst_width, dst_height,
                                zoom_val, mirror, isNeedCrop,
                                isDstNV21, is16Align, isYuyvFormat);
                            if (ret44 != 0)
                            {
                                printf("888 rga_nv12_scale_crop failed, ret=%d\n", ret44);
                            }
                            else
                            {
                                printf("8888rga_nv12_scale_crop ok, ret=%d\n", ret44);
                            }
                        }

                        dst_fd = new_gb_shared_fd;

                    #endif

            }

            goto RECV_DATA;
		}
	}
 
	return 0 ;
}

#else

int main(int argc, char *argv[])
{

	int fd = ipc_fd_socket_init();

	return 0;
}

#endif